/**
 * 
 */
package vanhoc.android.mediakool;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;

import vanhoc.android.mediakool.R;
import vanhoc.android.mediakool.db.DatabaseHelper;
import vanhoc.android.medialcool.item.data.SongItemData;
import vanhoc.android.medialcool.utils.NotificationUtils;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.provider.Contacts.PhonesColumns;
import android.provider.Contacts.PhotosColumns;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;

/**
 * @author user
 *
 */
public class MediaPlayerService extends Service implements OnCompletionListener,
															OnSeekBarChangeListener {

	/**
	 * Doi tuong choi nhac
	 */
	public MediaPlayer mediaPlayer = new MediaPlayer();
	
	/**
	 * Id cua bai hat dang hat
	 */
	int _songID;
	
	/**
	 * fieldName :  ten truong nam trong songs table - cai ma se dua vao de lay ve ds se phat nhac (vd:  album  hoac artist hoac playlist ... hoac all)
	 */
	private String _fieldName;
	
	
	/**
	 * Gia tri cua  fieldName
	 * Vd: album(fieldName) = mp3.zing.vn -> lay ve ds nhung bai hat nam trong mp3.zing.vn (dc gui tu AlbumActivity)
	 * vd: song(fieldName) = all  -> lay ve ds phat nhac la tat ca cac  bai hat co trogn sdcard (dc gui tu AllSOngsActivity)
	 */
	private String _fieldValue;
	
	
	/**
	 * Bien cho biet co nghe toan bo ds bai hat lay ve theo flag hay khong?
	 */
	private Boolean _isPlayAll = false;
	
	/**
	 * Bien cho biet co xao tron ds song lay ve hay khong? 
	 */
	private Boolean _isShuffle = false;
	
	
	/**
	 * Thong tin ve bai hat dang hat
	 */
	SongItemData currentSongData;
	
	/**
	 * list id cua cac bai hat nam trong cung 1 playlist voi bai hat dang hat
	 */
	ArrayList<Integer> listSongID;
	
	
	/**
	 * database
	 */
	DatabaseHelper databaseHelper = new DatabaseHelper(MediaPlayerService.this);
	
	/**
	 * Repeat 1 bai nhac
	 */
	public boolean _isRepeat = false;
	
	/**
	 * Repeat playlist
	 */
	public boolean _isRepeatPlaylist = false;
	
	/**
	 * Seekbar 
	 */
	private SeekBar _seekBar;
	
	/**
	 * Handler
	 */
	Handler handler = new Handler();
	
	/**
	 * Context
	 */
	private Context sContext;
	
	/**
	 * Bien luu ds id cac bai hat ban dau khi chua bi xao tron
	 */
	private ArrayList<Integer> firstSongListID;
	
	/**
	 * Luu id cua playlist dc chon de phat nhac (neu user click vao 1 bai hat thuoc 1 playlist nao do hoac click vao menu play all(shuffle) )
	 */
	int playlist_id = 0;
	
	/**
	 * 
	 */
	public static final int NOTIFICATION_ID = 10001;
	
	/**
	 * 
	 */
    static final int PROGRESS_MAX = 100; 
    
	
    TelephonyManager telephonyManager;
    PhoneStateListener phoneStateListener;
    
    
    
    
	@Override
	public IBinder onBind(Intent intent) {
		/*trả về đối tượng IBinder cho phương thức onServiceConnected*/
		/*trả về chính lớp Service này*/
		PlayServiceBinder psb = new PlayServiceBinder();
		return psb;
	}
	
	
	
	/*tạo lớp binder*/
	public class PlayServiceBinder extends Binder {
		public MediaPlayerService getServiceHandle(){
			return MediaPlayerService.this;
		}
	}
	
	
	@Override
	public void onStart(Intent intent, int startId) {
		this._getIntentData(intent);
			
		super.onStart(intent, startId);
	}
	
	
	public void _mediaController() {
		//lay ve ds phat nhac theo fieldName va fieldValue nhan dc qua intent
		this.listSongID	=	getListSongID();
				
		//luu lai 1 ban ds bai hat nguyen mau (chua bi xao tron)
		setFirstSongListID(listSongID);
			
		//neu chon nghe toan bo thi se cho phat bai hat dau tien trong ds
		if (this._isPlayAll) {
			setSongID(listSongID.get(0));
		}
		
		//neu chon xao tron list thi tron list nhac xong roi moi cho phat bai hat dau tien trong ds
		if (this._isShuffle) {
			shuffleSongListID();
			setSongID(listSongID.get(0));
		}
				
		//choi nhac 
		this._playSong();
		
		
		//bat su kien co cuoc goi den
		if (mediaPlayer.isPlaying()) {
			telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
			
			// Create a new PhoneStateListener
			phoneStateListener = new PhoneStateListener(){
				@Override
				public void onCallStateChanged(int state, String incomingNumber) {
					// TODO Auto-generated method stub
					//super.onCallStateChanged(state, incomingNumber);
					switch (state) {
						case TelephonyManager.CALL_STATE_IDLE:
				          _play();
				          break;
				        case TelephonyManager.CALL_STATE_OFFHOOK:
				          break;
				        case TelephonyManager.CALL_STATE_RINGING:
				          _pause();
				          break;
					}
				}
			};
			
			
			 // Register the listener with the telephony manager
		    telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
		}
	}

	//lay ve du lieu thong qua intent
	private void _getIntentData(Intent intent) {
		//lay ve tieu chi get list song
		this._fieldName	=	intent.getExtras().getString("FIELDNAME");
		
		this._fieldValue	=	intent.getExtras().getString("FIELDVALUE");
				
		//isPlayall
		this._isPlayAll	=	intent.getExtras().getBoolean("PLAYALL_FEATURE");
		
		//isShuffle
		this._isShuffle	= intent.getExtras().getBoolean("SHUFFLE_FEATURE");
		
		//playlist id
		this.playlist_id = intent.getExtras().getInt("PLAYLIST_ID");
		
		Log.e("playlist_id", ""+playlist_id);
		
		if (this._isPlayAll == false && this._isShuffle== false) {
			int songId = intent.getExtras().getInt("songID");
			setSongID(songId);
		}
	}
	
	/**
	 * Set Danh sach nhac ban dau khi chua bi xao tron
	 */
	public void setFirstSongListID(ArrayList<Integer> listSongId){
		this.firstSongListID = listSongId;
	}
	
	/**
	 * Phuc hoi lai ds dang phat nhac  ve ds nguyen thuy ban dau chua bi xao  tron
	 */

	public void restoreSongListID(){
		this.listSongID = this.firstSongListID;
	}
	
	
	/**
	 * shuffle lai ds id song khi chon shuffle
	 */
	public void shuffleSongListID(){
		Collections.shuffle(this.listSongID);
	}
	
	/**
	 * Lay ve danh sach nhac theo flag
	 * Neu la "all" -> lay all song from sdcard
	 * Neu la "mp3.zing.vn" -> lay nhung bai hat thuoc album mp.zing.vn
	 * ...
	 * truong hop ngoai le : lay ve ds nhac theo playlist (dua vao pid)
	 * @return
	 */
	public ArrayList<Integer> getListSongID(){
		ArrayList<Integer> listSongID = new ArrayList<Integer>();
		
		databaseHelper.openToRead();
		if (this.playlist_id > 0) {
			listSongID = databaseHelper.getSongListIdByPlaylist(playlist_id);
		}else{
			//kiem tra fieldName xem lay ve ds nhac theo truong nao, va dua vao fieldValue de biet dc dieu kien loc du lieu
			if (this._fieldName.equals("song")) { //lay ve tca cac bai hat trong sdcard (nghia la truoc do nguoi dung chon nghe nhac tu AllSongsActivity)
				listSongID = databaseHelper.getAllSongID();
			}else{ //lay ve ds id cua nhung bai hat theo album hoac artist,genre
				listSongID = databaseHelper.getListSongIdByFieldName(_fieldName, _fieldValue);
			}
		}
		databaseHelper.close();
		
		
		return listSongID;
	}

	//Lay ve arraylist  chua id cua cac bai hat cung nam trong 1 playlist voi bai dang hat
	public ArrayList<Integer> getListSongID(int currentSongID){
		ArrayList<Integer> listID = new ArrayList<Integer>();
		databaseHelper.openToRead();
		Cursor cursor = databaseHelper.getListSongIdOfPlaylist(currentSongID);
 		cursor.moveToFirst();
 		for (int i = 0; i < cursor.getCount(); i++) {
 			listID.add(Integer.parseInt(cursor.getString(0)));
 			cursor.moveToNext();
 		}
 		databaseHelper.close();
		return listID;
	}

	
	@Override
	public void onDestroy() {
		super.onDestroy();
	}
    
	public void _stop() {
		mediaPlayer.stop();
	}

	// chi co nhiem vu la choi nhac
	public void _playSong() {
		//Lay ve thong tin cua bai hat dang choi
		this.currentSongData	=	this.getCurrentSong();
		//play song
		try {
			mediaPlayer.reset();
			mediaPlayer.setDataSource(this.currentSongData.getPath());
			mediaPlayer.prepare();
			mediaPlayer.start();
			mediaPlayer.setOnCompletionListener(this);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		}catch (IllegalStateException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}
		
		//toast notification
		toastNotification(true);
	}
	
	
	//Lay ve bai hat dang dc play voi cac thong tin : name, id , path...
	public SongItemData getCurrentSong() {
		SongItemData songInfo = new SongItemData();
 		databaseHelper.openToRead();
 		Cursor cursor = databaseHelper.getInfoSong(this._songID);
 		cursor.moveToFirst();
 		for (int i = 0; i < cursor.getCount(); i++) {
 			songInfo.setName(cursor.getString(0));
 			songInfo.setName(cursor.getString(1));
 			songInfo.setAlbum(cursor.getString(2));
 			songInfo.setArtist(cursor.getString(3));
 			songInfo.setDuration(cursor.getString(4));
 			songInfo.setPath(cursor.getString(5));
 			songInfo.setGenre(cursor.getString(6));
 			songInfo.setThumbPath(cursor.getString(7));
 			cursor.moveToNext();
 		}
 		databaseHelper.close();
 		return songInfo;
	}

	

	
	
	//Lay ve duration hien tai cua bai hat dang % -> update seekbar
	public int getCurrentSongDuration(){
		if(mediaPlayer!=null) {
			if(mediaPlayer.isPlaying()){
				int total = getSongDuration();
				int current = mediaPlayer.getCurrentPosition();
				
				return (int)(current*100/total);
			}
		}
		return 0;
	}
	
	//Lay ve total duration hien tai cua bai hat 
	public int getSongDuration(){
		return mediaPlayer.getDuration();
	}
	
	//Lay ve duration hien tai cua bai hat dang milliseconds -> update TextView currentDuration
	public int getMilliSecondsCurrentDuration(){
		return mediaPlayer.getCurrentPosition();
	}
	
	//play
	public void _play(){
		if (!mediaPlayer.isPlaying() || mediaPlayer == null) {
			mediaPlayer.start();
			//_startPlayProgressUpdater();
			
			toastNotification(true);
		}
	}
	
	
	//pause
	public void _pause(){
		if (mediaPlayer.isPlaying()) {
			mediaPlayer.pause();
			toastNotification(false);
		}
	}


	//Playing next song in the current playlist is playing
	public void _playNextSong() {
		//Lay ve id cua song hien tai trong listSong cung playlist
		//Neu bai hat do nam o cuoi danh sach thi khi click vao nut Next ben Activity -> choi lai bai hat dau tien
		//Neu bai hat do khong nam o cuoi danh sach thi choi bai hat tiep theo trong listSong do
		if (this._songID == this.listSongID.get(this.listSongID.size() - 1)) { //la bai hat cuoi cung trong playlist ->stop
			//Kiem tra xem co lap lai playlist hay khong.Neu co thi choi bai dau tien trong playlist.Neu ko thi stop
			if (_isRepeatPlaylist) {
				this._songID	=	this.listSongID.get(0);
				_playSong();
			}else{
				_pause();
			}
		}else{ //nguoc lai bai hat dang hat nam o giua playlist
			//lay ve vi tri cua bai hat dang hat trong listSong
			int currSongPos = getPositionCurrentSong(this._songID);
			//Cap nhat id cho this._songID
			this._songID	=	this.listSongID.get(currSongPos+1);
			_playSong();
		}
	}


	//Playing previous song in the current playlist is playing
	public void _playPreviousSong() {
		if (this._songID == this.listSongID.get(0)) {
			//cap nhat lai id cua bai hat dang choi la bai hat co index = 0 trong listSong cung playlist
			this._songID	=	this.listSongID.get(this.listSongID.size() -1 );
		}else{ //nguoc lai bai hat dang hat nam o giua playlist
			//lay ve vi tri cua bai hat dang hat trong listSong
			int currSongPos = getPositionCurrentSong(this._songID);
			//Cap nhat id cho this._songID
			this._songID	=	this.listSongID.get(currSongPos-1);
		}
		//this.musicPlayerControl();
		this._playSong();
	}
	
	//Lay ve vi tri cua 1 songid trong danh sach chua cac songid nam cung playlist
	private int getPositionCurrentSong(int songID) {
		for (int i = 0; i < this.listSongID.size(); i++) {
			if (songID == this.listSongID.get(i)) {
				return i;
			}
		}
		return -1;
	}
	
	//change seekbar
	public void _changeSeekbar(View v){
		if (mediaPlayer.isPlaying()) {
			SeekBar sb = (SeekBar) v;
			mediaPlayer.seekTo(sb.getProgress());
			Log.e("seekbar", ""+sb.getProgress());
		}
	}

	/**
     * On Song Playing completed
     * if repeat is ON play same song again
     * if shuffle is ON play random song
     * */
	@Override
	public void onCompletion(MediaPlayer mp) {
		if (this._isRepeat == true) { //lap lai bai hat dang dang hat
			this._playSong();
		}else{
			this._playNextSong();
			SendMessageToActivity sendMessage = new SendMessageToActivity();
			sendMessage.run();
		}
	}
	
	//gui 1 message mang id cua bai hat tiep theo sang activity
	class SendMessageToActivity extends Thread{
		//gui message (la id cua bai hat ke tiep) qua activity de ben activity cap nhat lai cac TextView hien thi ten bai hat,ca si....
		@Override
		public void run() {
			Message msg = new Message();
			msg.arg1	=	MediaPlayerService.this._songID;
			((MusicPlayerActivity)sContext).msgHandler.sendMessage(msg);
		}
	}
	
	
	
	public void _startPlayProgressUpdater() {
		//Lay ve vi tri cua seekbar ( dang choi nhac den doan nao)
		_seekBar.setProgress(mediaPlayer.getCurrentPosition());
		if (mediaPlayer.isPlaying()) {
			Runnable notification = new Runnable() {
				
				@Override
				public void run() {
					_startPlayProgressUpdater();
				}
			};
			handler.postDelayed(notification, 1000);
		}else{
			mediaPlayer.pause();
			_seekBar.setProgress(0);
		}
	}
	
	
	
	
	public void setStateShufflePlaylist(Boolean state){
		this._isShuffle	=	state;
	}
	
	public void setStateRepeatSong(Boolean state){
		this._isRepeat	=	state;
	} 
	
	public Boolean getStateShufflePlaylist(){
		return this._isShuffle;
	}
	
	public Boolean getStateRepeateSong(){
		return this._isRepeat;
	}
	

	public void setSeekbar(SeekBar sb) {
		this._seekBar	=	sb;
	}

	
	
	
	@Override
	public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onStartTrackingTouch(SeekBar arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onStopTrackingTouch(SeekBar arg0) {
		// TODO Auto-generated method stub
		
	}

	//set context
	public void setContext(Context context) {
		this.sContext	=	context;
	}
	
	//set id bai hat se choif
	public void setSongID(int songid){
		this._songID	=	songid;
	}
	
	
	public int getSongID(){
		return this._songID;
	}
	
	/**
	 * Lap lai danh sach phat nhac
	 */
	public void _repeatPlaylist() {
		if (_isRepeatPlaylist) {
			_isRepeatPlaylist = false;
			Toast.makeText(getApplicationContext(), getResources().getString(R.string.repeat_off), Toast.LENGTH_LONG).show();
		}else{
			_isRepeatPlaylist = true;
			Toast.makeText(getApplicationContext(),  getResources().getString(R.string.repeat_on), Toast.LENGTH_LONG).show();
		}
	}
	
	
	private void toastNotification(Boolean state) {
    	//Get a reference to the NotificationManager:
    	NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    	
    	
    	HashMap<String, String> intentData = new HashMap<String, String>();
    	intentData.put("PLAYLIST_ID", ""+this.playlist_id);
    	intentData.put("FIELDNAME", this._fieldName);
    	intentData.put("FIELDVALUE", this._fieldValue);
    	intentData.put("SONGIDPLAYING", ""+this._songID);
    	
    	
    	NotificationUtils notificationUtils = new NotificationUtils(this, notificationManager);
    	notificationUtils.toastNotificationForMusicPlay(currentSongData.getName(), currentSongData.getArtist(), intentData,state);
	}
}
